<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Schema;

/**
 * Class Common
 * @package App\Model
 * @User    wuqin
 * @Date    2018/3/13 0013
 * @Time    19:28
 */
class Common extends Model
{
    /**
     * @var string
     */
//    protected $table = '';//表名
    /**
     * @var string
     */
//    protected $primaryKey = '';
    /**
     * @var string
     */
//    protected $dateFormat = 'U';
    /**
     * @var bool
     */
//    public $timestamps = false;
    /**
     * @var array
     */
//    protected $guard = [];
    /**
     * @var Common
     */
    public $model;

    /**
     * Common constructor.
     */
    function __construct()
    {
        parent::__construct();
        date_default_timezone_set('PRC');
        $this->model = $this;
    }

    /**
     * 方法 : get
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param       $arr
     * @param       $fields
     * @param int   $limit
     * @param int   $offset
     * @param array $orderBy
     * @return mixed
     */
    public function get($arr, $fields = "*", $limit = 0, $offset = 0, $orderBy = array())
    {
        if (!empty($arr)) {
            $this->splice_where($arr);
        }
        if ($limit != 0) {
            $this->model = $this->model->limit($limit);
        }

        if ($offset != 0) {
            $this->model = $this->model->offset($offset);
        }

        if (!empty($orderBy)) {
            $this->model = $this->model->orderBy($orderBy[0], $orderBy[1]);
        }
        $res = $this->model->select($fields)->get();
        return $res->toArray();
    }

    /**
     * 方法 : splice_where
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param $arr
     * @return array
     */
    public function splice_where($arr)
    {
        if (!is_array($arr)) {
            return array();
        }
        foreach ($arr as $k => $v) {
            switch ($v[0]) {
                case 'where':
                    $this->model = $this->model->where($v[1], $v[2], $v[3]);
                    break;
                case 'orWhere':
                    $this->model = $this->model->orWhere($v[1], $v[2], $v[3]);
                    break;
                case 'whereBetween':
                    $this->model = $this->model->whereBetween($v[1], $v[2]);
                    break;
                case 'whereNotBetween':
                    $this->model = $this->model->whereNotBetween($v[1], $v[2]);
                    break;
                case 'whereIn':
                    $this->model = $this->model->whereIn($v[1], $v[2]);
                    break;
                case 'whereNotIn':
                    $this->model = $this->model->whereNotIn($v[1], $v[2]);
                    break;
                case 'whereNull':
                    $this->model = $this->model->whereNull($v[1]);
                    break;
                case 'whereNotNull':
                    $this->model = $this->model->whereNotNull($v[1]);
                    break;
            }
        }
    }

    /**
     * 方法 : join_get
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param       $table_arr
     * @param       $table_id
     * @param       $id
     * @param array $arr
     * @param int   $limit
     * @param int   $offset
     * @return bool
     */
    public function join_get($table_arr, $table_id, $id, $arr = array(), $limit = 0, $offset = 0)
    {
        if (empty($table_arr) || empty($table_id)) {
            return false;
        }
        if (!is_array($table_arr) || !is_array($table_id) || (!empty($arr) && !is_array($arr))) {
            return false;
        }

        if (!empty($arr)) {
            $this->splice_where($arr);
        }
        foreach ($table_arr as $k => $v) {
            $this->model = $this->model->leftJoin($v, $this->table . '.' . $id[$k], '=', $table_id[$k]);
        }
        $res = $this->model->select(['*'])->get();
        return $res->toArray();
    }

    /**
     * 方法 : add
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param $arr
     * @return bool
     */
    public function add($arr)
    {
        if (!is_array($arr)) {
            return false;
        }
        $columns = $this->model->getColumns();
        $arr     = $this->model->filterInsertData($arr, $columns);
        if ($arr) {
            $res = $this->model->create($arr);
            return $res->toArray();
        }
        return false;
    }

    /**
     * 方法 : getColumns
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @return mixed
     */
    public function getColumns()
    {
        $coluumns = Schema::getColumnListing($this->model->table);
        return $coluumns;
    }

    /**
     * 方法 : filterInsertData
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param $filter_data
     * @param $insert_column
     * @return array|bool
     */
    public function filterInsertData($filter_data, $insert_column)
    {
        if (!$filter_data || !$insert_column) {
            return false;
        }
        if (is_array($filter_data[key($filter_data)])) {
            $flag = true;
            foreach ($filter_data as $k => $v) {
                $temp = array_intersect_key($v, array_flip($insert_column));
                if (!$temp) {
                    $flag = false;
                    break;
                } else {
                    $filter_data[$k] = $temp;
                }
            }
            if ($flag) {
                return $filter_data;
            } else {
                return false;
            }
        } else {
            return array_intersect_key($filter_data, array_flip($insert_column));
        }
    }

    /**
     * 方法 : updateData
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param $arr
     * @param $updateData
     * @return bool
     */
    public function updateData($arr, $updateData)
    {
        if (!$arr || !$updateData) {
            return false;
        }
        $this->splice_where($arr);
        return $this->model->update($updateData);
    }

    /**
     * 方法 : updateDataByPrimary
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param $id
     * @param $updateData
     * @return mixed
     */
    public function updateDataByPrimary($id, $updateData)
    {
        $obj = $this->find($id);
        return $obj->update($updateData);
    }

    /**
     * 方法 : deleteByPrimary
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param $id
     * @return mixed
     */
    public function deleteByPrimary($id)
    {
        $obj = $this->model->find($id);
        if (empty($obj) || empty($obj->toArray())) {
            return false;
        }
        return $obj->delete();
    }

    /**
     * 方法 : deleteByWhere
     * @User     wuqin
     * @DateTime 2018-04-13 13:22
     * @param $where
     * @return bool|null
     * @throws \Exception
     */
    public function deleteByWhere($where)
    {
        if (empty($where)) {
            return false;
        }
        $this->splice_where($where);
        return $this->model->delete();
    }

    /**
     * 方法 : checkUpdateData
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param $data
     * @return bool
     */
    public function checkUpdateData($data)
    {
        if (!isset($data) || count($data) <= 0) {
            return false;
        }
        //获取更新所需要的字段
        $update_fields = array_diff($this->model->getColumns(), $this->model->fillable);

        if (is_array($data[key($data)])) {
            foreach ($data as $key => $value) {
                if (count(array_diff(array_keys($value), $update_fields)) > 0) {
                    return false;
                }
            }
        } else {
            if (count(array_diff(array_keys($data), $update_fields)) > 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * 方法 : getColValue
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param $arr
     * @param $fields
     * @return mixed
     */
    public function getColValue($arr, $fields)
    {
        if (!empty($arr)) {
            $this->splice_where($arr);
        }
        $res = $this->model->lists($fields);
        return $res->toArray();
    }

    /**
     * 方法 : getSum
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @return mixed
     */
    public function getSum()
    {
        return $this->model->count();
    }


    /**
     * 方法 : getSumByWhere
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     * @param $arr
     * @return bool
     */
    public function getSumByWhere($arr)
    {
        if (!is_array($arr)) {
            return false;
        }
        $this->splice_where($arr);
        return $this->model->count();
    }


    /**
     * 方法 : trans_begin
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     */
    public function trans_begin()
    {
        DB::beginTransaction();
    }


    /**
     * 方法 : trans_rollback
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     */
    public function trans_rollback()
    {
        DB::rollBack();
    }

    /**
     * 方法 : trans_commit
     * @User     wuqin
     * @DateTime 2018-03-13 19:28
     */
    public function trans_commit()
    {
        DB::commit();
    }

    /**
     * 方法 : set_array_redis
     * @User     wuqin
     * @DateTime 2018-03-29 20:38
     * @param $key
     * @param $value
     * @return mixed
     */
    public function set_array_redis($key, $value, $time = 0)
    {
        return $time === 0 ? Redis::set($key, json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)) :
            Redis::set($key, json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "EX", $time);
    }

    /**
     * 方法 : set_string_redis
     * @User     wuqin
     * @DateTime 2018-03-29 20:38
     * @param $key
     * @param $value
     * @return mixed
     */
    public function set_string_redis($key, $value)
    {
        return Redis::set($key, $value);
    }

    /**
     * 方法 : exists_redis
     * @User     wuqin
     * @DateTime 2018-03-29 20:38
     * @param $key
     * @return mixed
     */
    public function exists_redis($key)
    {
        return Redis::exists($key);
    }

    /**
     * 方法 : set_empty_array_redis
     * @User     wuqin
     * @DateTime 2018-03-29 20:38
     * @param $key
     * @return bool
     */
    public function set_empty_array_redis($key)
    {
        if (empty($key)) {
            return [];
        }
        return Redis::set($key, '{}', 'EX', 100);
    }

    /**
     * 方法 : keys_redis
     * @User     wuqin
     * @DateTime 2018-03-29 20:38
     * @param $key
     * @return bool
     */
    public function keys_redis($key)
    {
        if (empty($key)) {
            return [];
        }
        return Redis::keys($key);
    }

    /**
     * 方法 : get_array_redis
     * @User     wuqin
     * @DateTime 2018-03-29 20:38
     * @param $key
     * @return bool|mixed
     */
    public function get_array_redis($key)
    {
        if (empty($key)) {
            return [];
        }
        $result = json_decode(Redis::get($key), true, 512, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        return empty($result) ? [] : $result;
    }

    /**
     * 方法 : get_redis
     * @User     wuqin
     * @DateTime 2018-03-29 20:38
     * @param $key
     * @return bool
     */
    public function get_redis($key)
    {
        if (empty($key)) {
            return [];
        }
        $result = json_decode(Redis::get($key), true, 512, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        return empty($result) ? [] : $result;
    }

    /**
     * 方法 : mget_array_redis
     * @User     wuqin
     * @DateTime 2018-03-29 20:38
     * @param $key
     * @return array|bool
     */
    public function mget_array_redis($key)
    {
        if (empty($key)) {
            return [];
        }
        $data   = Redis::mget($key);
        $result = array();
        //多维排序
        $parent = array();
        foreach ($data as $key => &$value) {
            $value = json_decode($value, true, 512, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            if (empty($value)) {
                continue;
            }

            $values             = array_values($value);
            $result[$values[0]] = $value;

            if (isset($value['parent_id'])) {
                $parent[] = $value['parent_id'];
            }
        }
        unset($value);
        if (!empty($result) && !empty($parent)) {
            array_multisort($parent, SORT_ASC, $result);
        }
        return $result;
    }

    /**
     * 方法 : del_redis
     * @User     wuqin
     * @DateTime 2018-03-29 20:38
     * @param $key
     * @return bool
     */
    public function del_redis($key)
    {
        if (empty($key)) {
            return [];
        }
        return Redis::del($key);
    }


}
